package com.diamondsys.embrapa.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.servlet.ServletRequest;
import javax.swing.text.MaskFormatter;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.mail.HtmlEmail;
import org.primefaces.context.RequestContext;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 * @author Rafael
 */
public class JsfUtil {

    static DateFormat formatDate = new SimpleDateFormat("dd/MM/yyyy");
    static DateFormat formatHour = new SimpleDateFormat("HH:mm:ss");

    /**
     *
     * @param entities
     * @param selectOne
     * @return
     */
    public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {
        int size = selectOne ? entities.size() + 1 : entities.size();
        SelectItem[] items = new SelectItem[size];
        int i = 0;
        if (selectOne) {
            items[0] = new SelectItem("", "---");
            i++;
        }
        for (Object x : entities) {
            items[i++] = new SelectItem(x, x.toString());
        }
        return items;
    }

    /**
     *
     * @return
     */
    public static boolean isValidationFailed() {
        return FacesContext.getCurrentInstance().isValidationFailed();
    }

    public static void setValidationFailed() {
        FacesContext.getCurrentInstance().validationFailed();
    }

    /**
     *
     * @param ex
     * @param defaultMsg
     */
    public static void addErrorMessage(Exception ex, String defaultMsg) {
        String msg = ex.getLocalizedMessage();
        if (msg != null && msg.length() > 0) {
            addErrorMessage(msg);
        } else {
            addErrorMessage(defaultMsg);
        }
    }

    /**
     *
     * @param messages
     */
    public static void addErrorMessages(List<String> messages) {
        for (String message : messages) {
            addErrorMessage(message);
        }
    }

    /**
     *
     * @param msg
     */
    public static void addErrorMessage(String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
        FacesContext.getCurrentInstance().addMessage(null, facesMsg);
    }

    /**
     *
     * @param msg
     */
    public static void addSuccessMessage(String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
        FacesContext.getCurrentInstance().addMessage("successInfo", facesMsg);
    }

    /**
     *
     * @param msg
     */
    public static void addWarningMessage(String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN, msg, msg);
        FacesContext.getCurrentInstance().addMessage("WarningInfo", facesMsg);
    }

    /**
     *
     * @param title
     * @param message
     * @param level
     */
    public static void showMessage(String title, String message, Severity level) {
        RequestContext.getCurrentInstance().showMessageInDialog(new FacesMessage(level, title, message));
    }

    /**
     *
     * @param key
     * @param obj
     */
    public static void AddSessionParameter(String key, Object obj) {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        Map<String, Object> sessionMap = externalContext.getSessionMap();
        sessionMap.put(key, obj);
    }

    /**
     *
     * @param key
     * @return
     */
    public static Object GetSessionParameter(String key) {
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);
    }

    /**
     *
     * @param key
     * @return
     */
    public static String getRequestParameter(String key) {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);
    }

    /**
     *
     * @param requestParameterName
     * @param converter
     * @param component
     * @return
     */
    public static Object getObjectFromRequestParameter(String requestParameterName, Converter converter, UIComponent component) {
        String theId = JsfUtil.getRequestParameter(requestParameterName);
        return converter.getAsObject(FacesContext.getCurrentInstance(), component, theId);
    }

    /**
     *
     */
    public static enum PersistAction {

        /**
         *
         */
        CREATE,
        /**
         *
         */
        DELETE,
        /**
         *
         */
        UPDATE
    }

    public static String encryptMD5(String string) {

        try {
            final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(string.getBytes(Charset.forName("UTF8")));
            final byte[] resultByte = messageDigest.digest();
            string = Hex.encodeHexString(resultByte);
        } catch (Exception ex) {
        }
        return string;
    }

    public static void sendEmailUsuarioNovo(String emailLogin, String nome, String senha) {
        boolean tryGmail = false;

        try {
            HtmlEmail email = new HtmlEmail();
            email.setHostName("garoupa.cnpso.embrapa.br");
            email.setAuthentication("ramos", "ramos2015");
            email.setSmtpPort(25);
            email.addTo(emailLogin, nome);
            email.setFrom("cadcli@cnpso.embrapa.br", "Embrapa Soja - Acesso");
            email.setSubject("Dados de acesso Embrapa Soja");

            // set the html message
            email.setHtmlMsg(String.format("<html><strong>Embrapa Soja</strong><br /><br />Prezado(a) Cliente<br /><p>O seu e-mail foi cadastrado no sistema de clientes da Embrapa Soja. Para que possamos mantê-lo informado sobre as tecnologias, produtos, serviços e eventos que envolvem a cultura da soja e girassol, no Brasil, e trigo no estado do Paraná, solicitamos que complete as informações no link abaixo.</p><br /><strong>&emsp;Dados de acesso<strong>&emsp;<a href=\"http://www.cnpso.embrapa.br/RelacionamentoCliente\" style=\"font-size: 1.3em\">http://www.cnpso.embrapa.br/RelacionamentoCliente</a><br /><br /><strong>&emsp;Usuário: %s</strong><br /><strong>&emsp;Senha: %s</strong><br /><br />Importante: caso não queira receber informações da Embrapa Soja, favor desconsiderar este e-mail.<br /><br />Atenciosamente<br /><br /><strong>Núcleo de Comunicação Organizacional<br />Embrapa Soja</strong><br /><br />Empresa Brasileira de Pesquisa Agropecuária (Embrapa)<br />Londrina/PR<br /><br />Fone: +55 (43) 3371 6000 | Fax: +55 (43) 3371 6100<br /><a href=\"http://www.embrapa.br/soja\">www.embrapa.br/soja</a><br />Facebook: <a href=\"http://www.facebook.com/embrapasoja.oficial\">www.facebook.com/embrapasoja.oficial</a></html>", emailLogin, senha));

            // set the alternative message
            email.setTextMsg(String.format("Acesse o sistema através de: http://pescada.cnpso.embrapa.br:8080/embrapa/faces/login/LoginCliente.xhtml  \n Usuário: %s \n Senha: %s  ", emailLogin, senha));

            // send the email
            email.send();
        } catch (Exception ex) {
            Logger.getLogger("Falha ao enviar Email: ").log(Level.SEVERE, null, ex);
            tryGmail = true;
        }

        if (tryGmail) {
            try {
                HtmlEmail email = new HtmlEmail();
                email.setHostName("smtp.gmail.com");
                email.setSSLCheckServerIdentity(true);
                email.setSslSmtpPort("465");
                email.setSSLOnConnect(true);
                email.setAuthentication("embrapasojacad@gmail.com", "cadcli2015");
                email.setBounceAddress("cadcli@cnpso.embrapa.br");
                email.addReplyTo("cadcli@cnpso.embrapa.br");

                email.addTo(emailLogin, nome);
                email.setFrom("cadcli@cnpso.embrapa.br", "Embrapa Soja - Acesso");
                email.setSubject("Dados de acesso Embrapa Soja");

                // set the html message
                email.setHtmlMsg(String.format("<html><strong>Embrapa Soja<strong><br />Prezado(a) cliente<br /><p>O seu cadastro básico foi realizado no sistema da Embrapa Soja. Para que possamos manter contato e informá-lo sobre as tecnologias, produtos, serviços e eventos sobre a cultura da soja, girassol e trigo para o Paraná, por favor complete as informações de seu cadastro no link abaixo.</p><strong>&emsp;Dados de acesso<strong>&emsp;<a href=\"http://pescada.cnpso.embrapa.br:8080/embrapa/faces/login/LoginCliente.xhtml\" style=\"font-size: 1.3em\">http://pescada.cnpso.embrapa.br:8080/embrapa/faces/login/LoginCliente.xhtml</a><br /><br /><strong>&emsp;Usuário: %s</strong><br /><strong>&emsp;Senha: %s</strong><br /><br />Importante: Caso não queira receber informações da Embrapa Soja em seu e-mail, favor desconsiderar este email.<br /><br />Atenciosamente<br />Núcleo de Comunicação Organizacional<br />Embrapa Soja<br />Empresa Brasileira de Pesquisa Agropecuária (Embrapa)<br />Londrina/PR<br />Fone: +55 (43) 3371 6000 | Fax: +55 (43) 3371 6100<br /><a href=\"http://www.embrapa.br/soja\">www.embrapa.br/soja</a><br />Facebook: <a href=\"http://www.facebook.com/embrapasoja.oficial\">www.facebook.com/embrapasoja.oficial</a></html>", emailLogin, senha));

                // set the alternative message
                email.setTextMsg(String.format("Acesse o sistema através de: http://pescada.cnpso.embrapa.br:8080/embrapa/faces/login/LoginCliente.xhtml  \n Usuário: %s \n Senha: %s  ", emailLogin, senha));

                // send the email
                email.send();
            } catch (Exception ex) {
                Logger.getLogger("Falha ao enviar Email: ").log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     *
     * @param fileName
     * @param in
     * @return
     */
    public static String copyFile(String fileName, InputStream in) {
        try {
            // write the inputStream to a FileOutputStream

            String fullpath = ((ServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getServletContext().getRealPath("/").concat("/uploadedFiles/").concat(fileName);
            OutputStream out = new FileOutputStream(new File(fullpath));

            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = in.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }

            in.close();
            out.flush();
            out.close();

            System.out.println("New file created! " + fullpath);
            return fullpath;
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }

        return "";
    }

    /**
     *
     * @param fileName
     * @return
     */
    public static Map<String, String> parseCSV(String fileName) {

        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = ",";
        Map<String, String> maps = new HashMap<String, String>();

        try {

            br = new BufferedReader(new FileReader(fileName));
            while ((line = br.readLine()) != null) {

                // use comma as separator
                String[] campos = line.split(cvsSplitBy);

                maps.put(campos[0], (campos.length > 1) ? campos[1] : "");

            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return maps;

    }

    /**
     *
     * @param fileName
     * @return
     */
    public static List<String[]> parseCSVLines(String fileName) {

        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = "\n";
        List<String[]> result = new ArrayList<String[]>();

        try {

            br = new BufferedReader(new FileReader(fileName));
            while ((line = br.readLine()) != null) {

                result.add(line.split(";"));

            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return result;

    }

    public static String formatPhone(String telefone) {
        try {
            if (telefone.length() < 10) {
                telefone = new String(new char[10 - telefone.length()]).replace("\0", "0") + telefone;
            }

            String mascara = "(##) ####-####";

            MaskFormatter maskFormatter = new MaskFormatter(mascara);
            maskFormatter.setAllowsInvalid(true);
            maskFormatter.setPlaceholderCharacter('0');
            maskFormatter.setValueContainsLiteralCharacters(false);
            return maskFormatter.valueToString(telefone);

        } catch (Exception ex) {
            return telefone;
        }
    }

    public static String customFormatDate(Date date) {
        if (date != null) {
            return formatDate.format(date);
        }
        return "";
    }

    public static String customFormatHour(Date date) {
        if (date != null) {
            return formatHour.format(date);
        }
        return "";
    }
    
    public static String formatCep(String cep) {
        try {
            String mascara = "#####-###";

            MaskFormatter maskFormatter = new MaskFormatter(mascara);
            maskFormatter.setAllowsInvalid(true);
            maskFormatter.setPlaceholderCharacter('0');
            maskFormatter.setValueContainsLiteralCharacters(false);
            return maskFormatter.valueToString(cep);

        } catch (Exception ex) {
            return cep;
        }
    }

    public static String formatDate(Date date) {
        try {
            return new SimpleDateFormat("dd/MM/yyyy").format(date);

        } catch (Exception ex) {
            return date.toString();
        }
    }
    
   private static final int[] pesoCPF = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2};
   private static final int[] pesoCNPJ = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};

   private static int calcularDigito(String str, int[] peso) {
      int soma = 0;
      for (int indice=str.length()-1, digito; indice >= 0; indice-- ) {
         digito = Integer.parseInt(str.substring(indice,indice+1));
         soma += digito*peso[peso.length-str.length()+indice];
      }
      soma = 11 - soma % 11;
      return soma > 9 ? 0 : soma;
   }

   public static boolean isValidCPF(String cpf) {
      if ((cpf==null) || (cpf.length()!=11)) return false;

      Integer digito1 = calcularDigito(cpf.substring(0,9), pesoCPF);
      Integer digito2 = calcularDigito(cpf.substring(0,9) + digito1, pesoCPF);
      return cpf.equals(cpf.substring(0,9) + digito1.toString() + digito2.toString());
   }

   public static boolean isValidCNPJ(String cnpj) {
      if ((cnpj==null)||(cnpj.length()!=14)) return false;

      Integer digito1 = calcularDigito(cnpj.substring(0,12), pesoCNPJ);
      Integer digito2 = calcularDigito(cnpj.substring(0,12) + digito1, pesoCNPJ);
      return cnpj.equals(cnpj.substring(0,12) + digito1.toString() + digito2.toString());
   }    
}
